use std::sync::{
	atomic::{AtomicU64, Ordering},
	LazyLock, OnceLock,
};

use bytes::{Bytes, BytesMut};
use regex::bytes::CaptureLocations;
use tools::utils::bytes::location_value_curr_line;

use super::{
	head::{SipHeadField, CSEQ, TO},
	SipMethod, SipResponse, CRLF, DOUBLE_QUOTATION, HEAD_SEPARATOR, SEPARATOR, SIP_URL_PREFIX,
	SIP_URL_SUFFIX, SIP_VERSION, TAG_PREFIX,
};

#[inline]
pub(crate) fn get_bytes_str<'a>(buf: &'a Bytes) -> &'a str {
	let b = buf.as_ref();

	unsafe { std::str::from_utf8_unchecked(b) }
}

#[inline]
pub(crate) fn get_str<'a>(buf: &'a [u8]) -> &'a str {
	unsafe { std::str::from_utf8_unchecked(buf) }
}

#[inline]
pub fn is_whitespace(b: u8) -> bool {
	match b {
		b' ' | 0x09..=0x0d => true,
		_ => false,
	}
}

///将一个bytes当成str.去除两边多余的空格数据
///
/// skip:在处理前跳过的长度,
/// 要求:skip< b.len() 否则返回空内容
#[inline]
pub fn trim_and_skip(b: &Bytes, skip: usize) -> Bytes {
	if skip >= b.len() {
		return Bytes::default();
	}

	let mut s = skip;
	let mut e = b.len();

	for i in skip..b.len() {
		if !is_whitespace(b[i]) {
			s = i;
			break;
		}
	}

	for i in (skip..b.len()).rev() {
		if !is_whitespace(b[i]) {
			e = i;
			break;
		}
	}

	b.slice(s..e + 1)
}

///将一个bytes当成str.去除两边多余的空格数据
///
/// 此方法可以指定起始和结束位置.
#[inline]
pub fn trim_slice(b: &Bytes, start: usize, end: usize) -> Bytes {
	let mut s = start;
	let mut e = end;

	for i in start..end {
		if !is_whitespace(b[i]) {
			s = i;
			break;
		}
	}

	for i in (start..end).rev() {
		if !is_whitespace(b[i]) {
			e = i;
			break;
		}
	}

	b.slice(s..e + 1)
}

#[inline]
pub(crate) fn generate_tag_value() -> [u8; 8] {
	static TAG_VALUE: AtomicU64 = AtomicU64::new(73184610904835076u64);
	generate_disorder_u8s(TAG_VALUE.fetch_add(72907555602776961, Ordering::Relaxed))
}

///获取sip身份数据..
/// 给出除 ";tag="之外的所有数据
///
/// 这个数据为:
/// "13693672903" <sip:13693672903@59.45.97.58>;tag=0FKKyXaD2y59D
/// <sip:02581023282@218.94.132.4:5060>
/// <tel:+8641183290408;cpc=ordinary>;tag=0xwqxgvg
/// "+864173371381"<tel:+864173371381;user=Phone>
/// 目前来将此值当成名称和tag两个部分..因此不解释前面的部分..在需要的时候直接当成字符串比较是否相同.
/// from没有必要拆开.to需要拆开.因为刚刚开始请求时没有to字段
///
pub(crate) fn position_to_tag<'a>(buf: &Bytes) -> (Bytes, Bytes) {
	let index = location_value_curr_line(buf, 0, b';');
	if index == 0 {
		(buf.clone(), Bytes::default())
	} else {
		let mut buf = buf.clone();
		let name = buf.split_to(index);

		(name, buf)
	}

	// //一个SIPURI的正则表示.可以从这个里面取出/tag
	// static REGEX_SIP_URI: OnceLock<regex::bytes::Regex> = OnceLock::new();
	// let re = REGEX_SIP_URI.get_or_init(|| regex::bytes::Regex::new(r" *(.*>)(;tag=.+)?").unwrap());

	// match re.captures(&buf) {
	// 	Some(cap) => {
	// 		let name = match cap.get(1) {
	// 			Some(m) => buf.slice(m.start()..m.end()),
	// 			None => Bytes::default(),
	// 		};
	// 		let tag = match cap.get(2) {
	// 			Some(m) => buf.slice(m.start()..m.end()),
	// 			None => Bytes::default(),
	// 		};

	// 		(name, tag)
	// 	}
	// 	None => return (Bytes::default(), Bytes::default()),
	// }
}

///提取指定sip字段中的号码地址
///
/// 返回的两个值分别是: 号码和地址
/// 有可能存在'<>' 也有可能不存在
/// 目前处理如下:
/// <sip:02581023286@218.94.132.4:5060>
/// sip:02581023286@218.94.132.4:5060
/// "+864173454057"<tel:+864173454057;user=Phone>
pub fn fetch_number<'a>(buf: &Bytes) -> (Bytes, Bytes) {
	//一个SIPURI的正则表示.从中取出号码
	static SIP_NUM: LazyLock<regex::bytes::Regex> =
		LazyLock::new(|| regex::bytes::Regex::new(r"(sip:|tel:)(.+?)[@;](.*?)([;>]|$)").unwrap());

	let mut locs = SIP_NUM.capture_locations();
	SIP_NUM.captures_read(&mut locs, &buf);

	//没有找到就给一个0出去
	let (ns, nd) = locs.get(2).unwrap_or((0, 0));
	let (is, id) = locs.get(3).unwrap_or((0, 0));

	(buf.slice(ns..nd), buf.slice(is..id))
}

///直接读出cseq的值..因为大多数时候要使用到
#[inline]
pub(crate) fn cseq_num(buf: &Bytes) -> u32 {
	let (v, _) = load_separator_tow_value(buf);

	v.parse().unwrap_or(1)
}

///使用空格分格符取出两个值的方法
#[inline]
pub(crate) fn load_separator_tow_value<'a>(buf: &'a Bytes) -> (&'a str, &'a str) {
	//代表一个用空格分隔的两个字符串
	static REGEX_SIP_URI: OnceLock<regex::bytes::Regex> = OnceLock::new();
	let re = REGEX_SIP_URI.get_or_init(|| regex::bytes::Regex::new(r"(.+?) +(.+)").unwrap());

	let mut locs = re.capture_locations();
	re.captures_read(&mut locs, &buf);
	let (_, ind) = load_regex_location(&locs, 1);
	let (s, _) = load_regex_location(&locs, 2);

	(get_str(&buf[..ind]), get_str(&buf[s..]))
}

#[inline]
pub(crate) fn load_regex_location(locs: &CaptureLocations, get_loc: usize) -> (usize, usize) {
	(
		locs.get(get_loc).unwrap_or((0, 0)).0,
		locs.get(get_loc).unwrap_or((0, 0)).1,
	)
}

///将一个u64数字,转换成一定可见的值
#[inline]
pub(crate) fn generate_disorder_u8s(s: u64) -> [u8; 8] {
	static TAB: [u8; 64] = [
		b'w', b'x', b'y', b'z', b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L',
		b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'_', b'.',
		b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'0', b'a', b'b', b'c', b'd', b'e', b'f',
		b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v',
	];

	let mut b: [u8; 8] = unsafe { std::mem::transmute(s) };
	for i in 0..8 {
		b[i] = TAB[(b[i] & 63) as usize]
	}

	b
}

// ///将一个u128数字,转换成一定可见的值
// #[inline]
// pub(crate) fn generate_disorder_u128_to_u8s(s: u128) -> [u8; 16] {
// 	static TAB: [u8; 64] = [
// 		b'w', b'x', b'y', b'z', b'A', b'B', b'C', b'D', b'E', b'F', b'G', b'H', b'I', b'J', b'K', b'L',
// 		b'M', b'N', b'O', b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W', b'X', b'Y', b'Z', b'_', b'.',
// 		b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'0', b'a', b'b', b'c', b'd', b'e', b'f',
// 		b'g', b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o', b'p', b'q', b'r', b's', b't', b'u', b'v',
// 	];

// 	let mut b: [u8; 16] = unsafe { std::mem::transmute(s) };
// 	for i in 0..16 {
// 		b[i] = TAB[(b[i] & 63) as usize]
// 	}

// 	b
// }

///生成一个sip的url....带着名称.号码.
///
///
///"abc" <sip:13959394782@183.218.88.21>;tag=NXpQHHcS1vvpm
/// 是否生成tag.则由with_tag控制
#[inline]
pub(crate) fn generate_full_sip_url(name: &str, num: &str, ip: &str, with_tag: bool) -> Bytes {
	let mut buf = BytesMut::with_capacity(120);

	if !name.is_empty() {
		buf.extend_from_slice(DOUBLE_QUOTATION);
		buf.extend_from_slice(name.as_bytes());
		buf.extend_from_slice(DOUBLE_QUOTATION);
	}
	buf.extend_from_slice(SIP_URL_PREFIX);
	buf.extend_from_slice(num.as_bytes());
	buf.extend_from_slice(b"@");
	buf.extend_from_slice(ip.as_bytes());
	buf.extend_from_slice(SIP_URL_SUFFIX);
	if with_tag {
		buf.extend_from_slice(TAG_PREFIX);
		buf.extend_from_slice(&generate_tag_value());
	}

	buf.freeze()
}

pub trait WriteSip {
	///向buf内写入一个sip消息第一行的数据..
	fn put_head_field(&mut self, f_name: &[u8], f_value: &[u8]);
	///向buf内写入一个sipRequest头格式数据.
	fn put_sip_request(&mut self, method: SipMethod, sip_url: &[u8]);
	///向buf内写入一个sipResp头格式数据.
	fn put_sip_response(&mut self, resp: &SipResponse);

	fn put_heads_end(&mut self);
	///写入当前一个完整的head字段.
	fn put_unbroken_head(&mut self, name: &SipHeadField);
	///写入cseq
	fn put_cseq_head(&mut self, cseq_value: u32, name_f: &[u8]);
	///写入to的头值
	fn put_head_by_to_value(&mut self, to_name: &Bytes, to_tag: &Bytes);

	///使用一个回调用来写入多种可能的值
	/// 回调函数写入value部分的内容
	/// 由于是回调,必须保证回调函数写入的有内容..
	#[allow(unused)]
	fn put_head_with_cb<T>(&mut self, f_name: &[u8], value: &T)
	where
		T: WriteCallBack;
	fn put_head_fn<F>(&mut self, f_name: &[u8], f: F)
	where
		F: FnOnce(&mut Self);

	///用来处理一些特殊的处理方式....传递一个回调函数,回调函数写入value部分的内容
	#[allow(unused)]
	fn put_head_fn_bytes<F>(&mut self, f_name: &[u8], f: F, buf: &Bytes)
	where
		F: FnOnce(&mut Self, &Bytes);
}

impl WriteSip for BytesMut {
	///写入cseq
	#[inline]
	fn put_cseq_head(&mut self, cseq_value: u32, name_f: &[u8]) {
		self.extend_from_slice(CSEQ);
		self.extend_from_slice(HEAD_SEPARATOR);
		self.extend_from_slice(cseq_value.to_string().as_bytes());
		self.extend_from_slice(SEPARATOR);
		self.extend_from_slice(name_f);
		self.extend_from_slice(CRLF);
	}

	#[inline]
	fn put_head_by_to_value(&mut self, to_name: &Bytes, to_tag: &Bytes) {
		self.extend_from_slice(TO);
		self.extend_from_slice(HEAD_SEPARATOR);
		self.extend_from_slice(to_name);
		if !to_tag.is_empty() {
			self.extend_from_slice(to_tag);
		}

		self.extend_from_slice(CRLF)
	}

	///写入一个sip消息第一行的数据..
	#[inline]
	fn put_head_field(&mut self, f_name: &[u8], f_value: &[u8]) {
		if f_value.is_empty() {
			return;
		}

		self.extend_from_slice(f_name);
		self.extend_from_slice(HEAD_SEPARATOR);
		self.extend_from_slice(f_value);
		self.extend_from_slice(CRLF);
	}

	///向buf内写入一个sipRequest头格式数据.
	#[inline]
	fn put_sip_request(&mut self, method: SipMethod, sip_url: &[u8]) {
		self.extend_from_slice(method.as_bytes());
		self.extend_from_slice(SEPARATOR);
		self.extend_from_slice(sip_url);
		self.extend_from_slice(SEPARATOR);
		self.extend_from_slice(SIP_VERSION);
		self.extend_from_slice(CRLF);
	}

	#[inline]
	fn put_heads_end(&mut self) {
		self.extend_from_slice(CRLF);
	}

	#[inline]
	fn put_unbroken_head(&mut self, name: &SipHeadField) {
		name.write(self);
	}

	#[inline]
	fn put_sip_response(&mut self, resp: &SipResponse) {
		let b: &str = (*resp).into();
		self.extend_from_slice(b.as_bytes());
		self.extend_from_slice(CRLF);
	}

	///调用某个对象的自身写入方法进行写入操作
	fn put_head_with_cb<T>(&mut self, f_name: &[u8], f: &T)
	where
		T: WriteCallBack,
	{
		self.extend_from_slice(f_name);
		self.extend_from_slice(HEAD_SEPARATOR);
		f.write(self);
		self.extend_from_slice(CRLF);
	}

	#[inline]
	fn put_head_fn<F>(&mut self, f_name: &[u8], f: F)
	where
		F: FnOnce(&mut Self),
	{
		self.extend_from_slice(f_name);
		self.extend_from_slice(HEAD_SEPARATOR);
		f(self);
		self.extend_from_slice(CRLF);
	}

	#[inline]
	fn put_head_fn_bytes<F>(&mut self, f_name: &[u8], f: F, buf: &Bytes)
	where
		F: FnOnce(&mut Self, &Bytes),
	{
		self.extend_from_slice(f_name);
		self.extend_from_slice(HEAD_SEPARATOR);
		f(self, buf);
		self.extend_from_slice(CRLF);
	}
}

pub(crate) trait WriteCallBack {
	fn write(&self, buf: &mut BytesMut);
}
